package org.martin.snsrs.client.services.http;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Random;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.message.BasicHeader;

class SimpleMultipartEntity implements HttpEntity {
	private static final char[] MULTIPART_CHARS = "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
			.toCharArray();
	private String boundary = null;
	boolean isSetFirst = false;
	boolean isSetLast = false;
	ByteArrayOutputStream out = new ByteArrayOutputStream();

	public SimpleMultipartEntity() {
		StringBuffer stringBuffer = new StringBuffer();
		Random localRandom = new Random();
		for (int i = 0; i < 30; i++)
			stringBuffer.append(MULTIPART_CHARS[localRandom
					.nextInt(MULTIPART_CHARS.length)]);
		this.boundary = stringBuffer.toString();
	}

	public void addPart(String paramString, File file, boolean paramBoolean) {
		try {
			addPart(paramString, file.getName(), new FileInputStream(file),
					paramBoolean);
			return;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

	public void addPart(String paramString1, String paramString2) {
		writeFirstBoundaryIfNeeds();
		try {
			this.out.write(("Content-Disposition: form-data; name=\""
					+ paramString1 + "\"\r\n\r\n").getBytes());
			this.out.write(paramString2.getBytes());
			this.out.write(("\r\n--" + this.boundary + "\r\n").getBytes());
			return;
		} catch (IOException localIOException) {
			localIOException.printStackTrace();
		}
	}

	public void addPart(String path, String fileName,
			InputStream fileStream, String contentType, boolean isBoundry) {
		writeFirstBoundaryIfNeeds();
		try {
			String str = "Content-Type: " + contentType + "\r\n";
			this.out.write(("Content-Disposition: form-data; name=\""
					+ path + "\"; filename=\"" + fileName + "\"\r\n")
					.getBytes());
			this.out.write(str.getBytes());
			this.out.write("Content-Transfer-Encoding: binary\r\n\r\n"
					.getBytes());
			byte[] buffer = new byte[4096];
			while (true) {
				int i = fileStream.read(buffer);
				if (i == -1)
					break;
				this.out.write(buffer, 0, i);
			}
		} catch (IOException localIOException2) {
			localIOException2.printStackTrace();
			try {
				if (!isBoundry)
					this.out.write(("\r\n--" + this.boundary + "\r\n")
							.getBytes());
				this.out.flush();
				try {
					fileStream.close();
					return;
				} catch (IOException localIOException4) {
					localIOException4.printStackTrace();
					return;
				}
			} catch (IOException localIOException3) {
				localIOException3.printStackTrace();
				return;
			}
		}
		try {
			fileStream.close();
		} catch (IOException localIOException1) {
			localIOException1.printStackTrace();
		}
	}

	public void addPart(String path, String name,
			InputStream inputStream, boolean isBoundry) {
		addPart(path, name, inputStream,
				"application/octet-stream", isBoundry);
	}

	public void consumeContent() throws IOException,
			UnsupportedOperationException {
		if (isStreaming())
			throw new UnsupportedOperationException(
					"Streaming entity does not implement #consumeContent()");
	}

	public InputStream getContent() throws IOException,
			UnsupportedOperationException {
		return new ByteArrayInputStream(this.out.toByteArray());
	}

	public Header getContentEncoding() {
		return null;
	}

	public long getContentLength() {
		writeLastBoundaryIfNeeds();
		return this.out.toByteArray().length;
	}

	public Header getContentType() {
		return new BasicHeader("Content-Type", "multipart/form-data; boundary="
				+ this.boundary);
	}

	public boolean isChunked() {
		return false;
	}

	public boolean isRepeatable() {
		return false;
	}

	public boolean isStreaming() {
		return false;
	}

	public void writeFirstBoundaryIfNeeds() {
		if (!this.isSetFirst)
			;
		try {
			this.out.write(("--" + this.boundary + "\r\n").getBytes());
			this.isSetFirst = true;
			return;
		} catch (IOException localIOException) {
			while (true)
				localIOException.printStackTrace();
		}
	}

	public void writeLastBoundaryIfNeeds() {
		if (this.isSetLast)
			return;
		try {
			this.out.write(("\r\n--" + this.boundary + "--\r\n").getBytes());
			this.isSetLast = true;
			return;
		} catch (IOException localIOException) {
			while (true)
				localIOException.printStackTrace();
		}
	}

	public void writeTo(OutputStream paramOutputStream) throws IOException {
		paramOutputStream.write(this.out.toByteArray());
	}
}